package com.warren.aop;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * @version V1.0
 * @Description:
 * @author: warren
 * @date: 2022/7/19$ 21:30$
 */
@Aspect
@Configuration
@Slf4j
public class LogRecordAspecct {
    /**
     * execution(),表达式的主题
     * 第一个"*",表示返回值类型任意
     * com.warren.controller aop所切的服务的包名，即我们的业务部分
     * 包名后面".." 表示当前包以及子包
     * 第二个"*"表示类名， *即所有类
     * .*(...),表示任何方法名，括号表示参数，两个点表示任何参数类型
     * execution(<修饰符模式>？<返回类型模式><方法名模式>(<参数模式>)<异常模式>?)
     */
    // 定义切点Pointcut
    @Pointcut("execution(* com.warren.controller..*.*(..))")
    public void excudeService() {

    }

    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();

        String url = request.getRequestURL().toString();
        String user = request.getHeader("user_id");
        String method = request.getMethod();
        String uri = request.getRequestURI();
        //记录一些请求参数
        try {
            Object[] args = pjp.getArgs();
            String queryString = JSON.toJSONString(args);
            log.info("\n" + "用户 {} 请求, url: {}, method: {}, uri: {}, params: {}" + "\n", user, url, method, uri, queryString);
        } catch (Exception e) {
            log.info("\n" + "用户 {} 请求, url: {}, method: {}, uri: {}" + "\n", user, url, method, uri);
        }
        // result 拦截方法的返回值
        Object result = pjp.proceed();
        log.info("请求结束， 返回数据: " + "\n" + JSON.toJSONString(result) + "\n");
        return result;
    }
}
